#ifndef CAN_MOTOR_H
#define CAN_MOTOR_H
#define GM6020_VOLTMODE
#include "struct_typedef.h"

#define CHASSIS_UPGIMBAL_CAN hcan1
#define CHASSIS_CAN hcan2
//云台和底盘使用的是不同的中心板，连接了不同的can端口。
//解决冲突和吞吐率问题，接线时需要注意。
//当我们使用同一个端口时，可以修改为
// #define GIMBAL_CAN hcan1

//电机的类型和约定的id枚举类型。通过修改这里的值对应更改电机
#ifdef GM6020_CURRENTMODE
typedef enum
{
    CAN_FROM_GIMBAL_XYW=0x2FE,
    
    CAN_CHASSIS_M_CAN2_ID = 0x200, //表示底盘上M3508在CAN2上的标识符
    CAN_CHASSIS_LF_M = 0x201,
    CAN_CHASSIS_RF_M = 0x202,
    CAN_CHASSIS_RB_M = 0x203,
    CAN_CHASSIS_LB_M = 0x204,

    CAN_CHASSIS_G_CAN1_ID = 0x1FE, //底盘GM6020
    CAN_CHASSIS_LF_G = 0x205,
    CAN_CHASSIS_RF_G = 0x206,
    CAN_CHASSIS_RB_G = 0x207,
    CAN_CHASSIS_LB_G = 0x208,

    CAN_DOWN_M_CAN2_ID = 0x1FF, //下云台
    CAN_DOWN_G_CAN2_ID = 0x2FE,
    CAN_DOWN_M_CAN1_ID = 0x1FF, //拨弹
    CAN_DOWN_G_CAN1_ID = 0x2FE, //yawdown
    CAN_YAW_UP = 0x209,
    CAN_PITCH_DOWN = 0x20A,
    CAN_SHOOT_DOWN_L = 0x205,
    CAN_SHOOT_DOWN_R = 0x206,
    CAN_SHOOT_DOWN_TRIGGER_1 = 0x207,
    CAN_SHOOT_DOWN_TRIGGER_2 = 0x208,
    CAN_SHOOT_DOWN_YAW_DOWN = 0x209,

    CAN_UP_M_CAN1_ID = 0x200,  //上云台
    CAN_UP_G_CAN1_ID = 0x2FE,
    CAN_PITCH_UP = 0x209,
    CAN_SHOOT_UP_L = 0x202,
    CAN_SHOOT_UP_R = 0x203,
    CAN_SHOOT_UP_TRIGGER = 0x204,

} can_msg_id_e;
#endif

#ifdef GM6020_VOLTMODE
typedef enum
{
    CAN_FROM_GIMBAL_XYW=0x2FF,
    
    CAN_CHASSIS_M_CAN2_ID = 0x200, //表示底盘上M3508在CAN2上的标识符
    CAN_CHASSIS_LF_M = 0x201,
    CAN_CHASSIS_RF_M = 0x202,
    CAN_CHASSIS_RB_M = 0x203,
    CAN_CHASSIS_LB_M = 0x204,

    CAN_CHASSIS_G_CAN1_ID = 0x1FF, //底盘GM6020
    CAN_CHASSIS_LF_G = 0x205,
    CAN_CHASSIS_RF_G = 0x206,
    CAN_CHASSIS_RB_G = 0x207,
    CAN_CHASSIS_LB_G = 0x208,

    CAN_DOWN_M_CAN2_ID = 0x1FF, //下云台
    CAN_DOWN_G_CAN2_ID = 0x2FF,
    CAN_DOWN_M_CAN1_ID = 0x1FF, //拨弹
    CAN_DOWN_G_CAN1_ID = 0x2FF, //yawdown
    CAN_YAW_UP = 0x209,
    CAN_YAW_DOWN = 0x209,
    CAN_PITCH_DOWN = 0x20A,
    CAN_SHOOT_DOWN_L = 0x205,
    CAN_SHOOT_DOWN_R = 0x206,
    CAN_SHOOT_DOWN_TRIGGER_1 = 0x207,
    CAN_SHOOT_DOWN_TRIGGER_2 = 0x208,
    CAN_SHOOT_DOWN_YAW_DOWN = 0x209,

    CAN_UP_M_CAN1_ID = 0x200,  //上云台
    CAN_UP_G_CAN1_ID = 0x2FF,
    CAN_PITCH_UP = 0x209,
    CAN_SHOOT_UP_L = 0x202,
    CAN_SHOOT_UP_R = 0x203,
    CAN_SHOOT_UP_TRIGGER = 0x204,

} can_msg_id_e;
#endif
//电机的虚拟ID枚举,根据情况注释[节约内存]
typedef enum
{
    // YAW_UP,
    // PITCH_DOWN,
    // PITCH_UP,
    // SHOOT_DOWN_L,
    // SHOOT_DOWN_R,
    // SHOOT_UP_L,
    // SHOOT_UP_R,
    // SHOOT_UP_TRIGGER,
    //下面的顺序不能改变
    CHASSIS_LF_M,         //M3508
    CHASSIS_RF_M,
    CHASSIS_RB_M,
    CHASSIS_LB_M,
    CHASSIS_LF_G,          //GM6020
    CHASSIS_RF_G,
    CHASSIS_RB_G,
    CHASSIS_LB_G,
    YAW_DOWN,           
    // SHOOT_DOWM_TRIGGER,
    //下面可以继续加
    LENGTH_OF_MOTOR_ID,
    
} motor_virtual_ID;

// 电机数据结构体。
typedef struct
{
    uint16_t ecd;
    int16_t speed_rpm;
    int16_t current_or_torque;//M3508/GM6020_or_M2006
    uint8_t temperate_or_null; //M3508/GM6020_or_M2006
    int16_t last_ecd;
} motor_measure_t;

//上云台发送的数据结构体
typedef struct
{
    int8_t x;		//[-127,127]线性映射
    int8_t y;		//
    int8_t w;		//
    int8_t nextmode; //下一个模式
}fromGimbalSTM_t;

void CAN_cmd_chassis_M3508(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4);
void CAN_cmd_chassis_GM6020(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4);
void CAN_cmd_chassis_OTHERS(int16_t motor1, int16_t motor2);

// 用于给外面的函数提供数据

/**
  * @brief          返回底盘电机 3508电机数据指针
  * @param[in]      i: 电机编号,范围[0,3]
  * @retval         电机数据指针
  */
extern const motor_measure_t *get_chassis_motor_measure_point(uint8_t i);

extern const fromGimbalSTM_t *get_gimbal_stm_point(void);
#endif


